package aliyun

import (
	"bytes"
	"crypto/hmac"
	"crypto/sha1"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"io/ioutil"
	"net/http"
	"net/url"
	"sort"
	"time"
)

// SignRequest 生成阿里云 API 签名
func SignRequest(accessKeyID, accessKeySecret, method, domain, path string, params map[string]string) string {
	// 1. 规范化参数
	keys := make([]string, 0, len(params))
	for k := range params {
		keys = append(keys, k)
	}
	sort.Strings(keys)
	query := url.Values{}
	for _, k := range keys {
		query.Add(k, params[k])
	}
	canonicalQuery := query.Encode()

	// 2. 构造待签名字符串
	date := time.Now().UTC().Format("2006-01-02T15:04:05Z")
	stringToSign := fmt.Sprintf(
		"%s\n%s\n%s\n%s",
		method,
		"", // Accept
		"", // Content-MD5
		fmt.Sprintf("x-acs-date:%s\nx-acs-signature-method:HMAC-SHA1\nx-acs-signature-nonce:%s\nx-acs-version:2019-09-30\n/%s?%s",
			date,
			fmt.Sprintf("%d", time.Now().UnixNano()),
			path,
			canonicalQuery,
		),
	)

	// 3. 计算签名
	h := hmac.New(sha1.New, []byte(accessKeySecret+"&"))
	h.Write([]byte(stringToSign))
	signature := base64.StdEncoding.EncodeToString(h.Sum(nil))

	// 4. 构造 Authorization 头
	return fmt.Sprintf("acs %s:%s", accessKeyID, signature)
}

type ImageSearchResponse struct {
	Data struct {
		Results []struct {
			Url string `json:"Url"`
		} `json:"Results"`
	} `json:"Data"`
}

// SearchImages 调用阿里云图像搜索
func SearchImages(accessKeyID, accessKeySecret, instanceID, keyword string) ([]string, error) {
	domain := "imagesearch.cn-shanghai.aliyuncs.com"
	path := "/v2/image/search"

	params := map[string]string{
		"InstanceId": instanceID,
		"Keyword":    keyword,
		"Start":      "0",
		"Num":        "10",
	}

	// 生成签名
	authorization := SignRequest(accessKeyID, accessKeySecret, "POST", domain, path, params)

	// 构造请求
	url := fmt.Sprintf("https://%s%s", domain, path)
	body, _ := json.Marshal(params)
	req, _ := http.NewRequest("POST", url, bytes.NewReader(body))

	// 设置请求头
	req.Header.Set("Authorization", authorization)
	req.Header.Set("x-acs-date", time.Now().UTC().Format("2006-01-02T15:04:05Z"))
	req.Header.Set("x-acs-signature-nonce", fmt.Sprintf("%d", time.Now().UnixNano()))
	req.Header.Set("Content-Type", "application/json")

	// 发送请求
	client := &http.Client{Timeout: 10 * time.Second}
	resp, err := client.Do(req)
	if err != nil {
		return nil, fmt.Errorf("请求失败: %v", err)
	}
	defer resp.Body.Close()

	// 解析响应
	respBody, _ := ioutil.ReadAll(resp.Body)
	var result ImageSearchResponse
	if err := json.Unmarshal(respBody, &result); err != nil {
		return nil, fmt.Errorf("解析响应失败: %v", err)
	}

	imageUrls := make([]string, 0)
	for _, item := range result.Data.Results {
		imageUrls = append(imageUrls, item.Url)
	}

	return imageUrls, nil
}
